package com.whfc.fse.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.whfc.common.enums.BindFlag;
import com.whfc.common.enums.NetState;
import com.whfc.common.exception.BizException;
import com.whfc.common.result.PageData;
import com.whfc.common.result.ResultEnum;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.PageUtil;
import com.whfc.fse.dao.FseGantryDataMapper;
import com.whfc.fse.dao.FseGantryMapper;
import com.whfc.fse.dto.FseGantryDTO;
import com.whfc.fse.dto.FseGantryDataDTO;
import com.whfc.fse.dto.FseGantryDataLogDTO;
import com.whfc.fse.dto.FseOperatorDTO;
import com.whfc.fse.entity.FseGantry;
import com.whfc.fse.entity.FseGantryData;
import com.whfc.fse.param.FseGantryAddParam;
import com.whfc.fse.param.FseGantryBindParam;
import com.whfc.fse.param.FseGantryEditParam;
import com.whfc.fse.param.FseGantryUnbindParam;
import com.whfc.fse.service.FseGantryService;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.influx.dao.FseGantryDataLogDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * @Description 龙门吊
 * @Author hw
 * @Date 2021-06-01 11:00
 * @Version 1.0
 */
@DubboService(interfaceClass = FseGantryService.class, version = "1.0.0")
public class FseGantryServiceImpl implements FseGantryService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private FseGantryMapper fseGantryMapper;

    @Autowired
    private FseGantryDataMapper fseGantryDataMapper;

    @Autowired
    private FseGantryDataLogDao fseGantryDataLogDao;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @Override
    public void add(FseGantryAddParam param) throws BizException {
        logger.info("新增龙门吊设备,param：{}", param);
        FseGantry fseGantry = new FseGantry();
        BeanUtils.copyProperties(param, fseGantry);
        //保存操作手
        List<FseOperatorDTO> list = param.getOperatorList();
        if (list != null && !list.isEmpty()) {
            fseGantry.setOperators(JSON.toJSONString(list));
        }
        fseGantryMapper.insertSelective(fseGantry);
        //初始化龙门吊初始数据
        FseGantryData gantryData = new FseGantryData();
        gantryData.setGantryId(fseGantry.getId());
        fseGantryDataMapper.insertSelective(gantryData);
    }

    @Override
    public void edit(FseGantryEditParam param) throws BizException {
        logger.info("修改龙门吊设备,param：{}", param);
        Integer gantryId = param.getGantryId();
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        if (fseGantry == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "龙门吊不存在");
        }
        BeanUtils.copyProperties(param, fseGantry);
        //保存操作手
        List<FseOperatorDTO> list = param.getOperatorList();
        fseGantry.setOperators(JSON.toJSONString(list));
        fseGantryMapper.updateByPrimaryKeySelective(fseGantry);
    }

    @Override
    public void del(Integer gantryId) throws BizException {
        logger.info("删除龙门吊,gantryId:{}", gantryId);
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        if (fseGantry == null) {
            throw new BizException(ResultEnum.PARAM_ERROR.getCode(), "该龙门吊不存在");
        }
        if (StringUtils.isNotBlank(fseGantry.getSn())) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该龙门吊已绑定硬件,不能删除");
        }
        fseGantryMapper.del(gantryId);
        fseGantryDataMapper.logicDelByGantryId(gantryId);
    }

    @Override
    public PageData<FseGantryDTO> list(Integer deptId, String keyword, Integer bindFlag, Integer netState, Integer pageNum, Integer pageSize) throws BizException {
        logger.info("龙门吊列表(分页),pageNum:{},pageSize:{},deptId:{},keyword:{},bindFlag:{},netState:{}",
                pageNum, pageSize, deptId, keyword, bindFlag, netState);
        PageHelper.startPage(pageNum, pageSize);
        List<FseGantryDTO> list = fseGantryMapper.selectFseGantryByDeptId(Collections.singletonList(deptId), keyword, bindFlag, netState);
        PageHelper.clearPage();

        for (FseGantryDTO fseGantryDTO : list) {
            handlerOperators(fseGantryDTO);
        }
        return PageUtil.pageData(PageInfo.of(list));
    }


    @Override
    public FseGantryDTO details(Integer gantryId) throws BizException {
        logger.info("龙门吊详情,gantryId:{}", gantryId);
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        FseGantryDTO gantryDTO = new FseGantryDTO();
        if (fseGantry != null) {
            BeanUtils.copyProperties(fseGantry, gantryDTO);
            handlerOperators(gantryDTO);
        }
        return gantryDTO;
    }

    @Override
    public List<FseGantryDTO> list(Integer deptId, String keyword, Integer bindFlag, Integer netState) throws BizException {
        logger.info("龙门吊列表(不分页),deptId:{},keyword:{},bindFlag:{},netState:{}",
                deptId, keyword, bindFlag, netState);
        List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(deptId);
        List<FseGantryDTO> list = fseGantryMapper.selectFseGantryByDeptId(deptIds, keyword, bindFlag, netState);
        for (FseGantryDTO fseGantryDTO : list) {
            handlerOperators(fseGantryDTO);
        }
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void bind(FseGantryBindParam param) throws BizException {
        logger.info("龙门吊绑定硬件服务,param:{}", param);
        Integer gantryId = param.getGantryId();
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        if (fseGantry == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该龙门吊不存在");
        }
        String sn = param.getSn();
        String platform = param.getPlatform();
        FseGantry gantry = fseGantryMapper.selectBySnAndPlatform(sn, platform);
        if (gantry != null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该硬件已被绑定");
        }
        fseGantryMapper.updateBindFlag(gantryId, platform, BindFlag.BIND.getValue(), sn,
                NetState.OFFLINE.getValue());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void unbind(FseGantryUnbindParam param) throws BizException {
        logger.info("龙门吊解绑硬件服务,param:{}", param);
        Integer gantryId = param.getGantryId();
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        if (fseGantry == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "该龙门吊不存在");
        }
        fseGantryMapper.updateBindFlag(gantryId, null, BindFlag.UNBIND.getValue(), null,
                NetState.OFFLINE.getValue());
    }

    @Override
    public FseGantryDataDTO monitor(Integer gantryId) throws BizException {
        logger.info("龙门吊监测,gantryId:{}", gantryId);
        FseGantry fseGantry = fseGantryMapper.selectByPrimaryKey(gantryId);
        if (fseGantry == null) {
            throw new BizException(ResultEnum.FAILURE.getCode(), "龙门吊不存在");
        }
        FseGantryData fseDeviceGantryData = fseGantryDataMapper.selectByGantryId(gantryId);
        FseGantryDataDTO dataDTO = new FseGantryDataDTO();
        if (fseDeviceGantryData == null) {
            return dataDTO;
        }
        BeanUtils.copyProperties(fseDeviceGantryData, dataDTO);
        Date now = new Date();
        Date startTime = DateUtil.getDateBegin(now);
        Date endTime = DateUtil.getDateEnd(now);
        int mainHookWarnNum = 0;
        int subHookWarnNum = 0;
        int windWarnNum = 0;
        List<FseGantryDataLogDTO> logs = fseGantryDataLogDao.selectGantryDataLogListByGantryId(gantryId, startTime, endTime);
        if (logs != null && !logs.isEmpty()) {
            mainHookWarnNum = logs.stream().mapToInt(FseGantryDataLogDTO::getMainHookTimeWarnNum).sum();
            subHookWarnNum = logs.stream().mapToInt(FseGantryDataLogDTO::getSubHookTimeWarnNum).sum();
            windWarnNum = logs.stream().mapToInt(FseGantryDataLogDTO::getWindTimeWarnNum).sum();
        }
        dataDTO.setMainHookWarnNum(mainHookWarnNum);
        dataDTO.setSubHookWarnNum(subHookWarnNum);
        dataDTO.setWindWarnNum(windWarnNum);
        return dataDTO;
    }

    @Override
    public List<FseGantryDataLogDTO> gantryLog(Integer gantryId, Date time) throws BizException {
        logger.info("龙门吊历史数据，gantryId：{}，time：{}", gantryId, time);
        Date startTime = DateUtil.getDateBegin(time);
        Date endTime = DateUtil.getDateEnd(time);
        return fseGantryDataLogDao.selectGantryDataLogListByGantryId(gantryId, startTime, endTime);
    }

    /**
     * 处理操作手
     *
     * @param fseGantryDTO
     */
    private void handlerOperators(FseGantryDTO fseGantryDTO) {
        String operators = fseGantryDTO.getOperators();
        List<FseOperatorDTO> operatorList = JSON.parseArray(operators, FseOperatorDTO.class);
        if (operatorList == null) {
            operatorList = new ArrayList<>();
        }
        fseGantryDTO.setOperatorList(operatorList);
        fseGantryDTO.setOperators(null);
    }

}
